package com.xyq.fs.search;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;

import com.xyq.fs.base.MyDirectoryS;
import com.xyq.fs.constants.FieldConstant;
import com.xyq.fs.constants.IndexStringConstants;
import com.xyq.fs.contants.filesuffixes2.TxtEnums;
import com.xyq.fs.entity.MyFile;
import com.xyq.fs.search.MyScoreUtil;
import com.xyq.fs.views.WindwosA;

public class MySearch {

	private static String[] QUERIES_INDEX_NAMES = { FieldConstant.FILE_NAME, FieldConstant.FILE_CONTENT };

	/**
	 * 生成一个查询query s
	 * 
	 * @param page
	 * @return
	 */
	public static Query buildQuery(SearchBody body) {

		if (body.getSearchKeys()[0].equals(""))
			body.setSearchKeys(new String[] { "测试一下哈哈哈" });

		BooleanQuery.Builder bQuery = new BooleanQuery.Builder();
		// 构建常规查询
		for (String key : body.getSearchKeys()) {
			BooleanQuery.Builder bQuery2 = new BooleanQuery.Builder();
			for (int y = 0; y < QUERIES_INDEX_NAMES.length; y++) {
				Query query2 = new PhraseQuery(0, QUERIES_INDEX_NAMES[y], key.split(""));
				bQuery2.add(query2, BooleanClause.Occur.SHOULD);
			}
			bQuery.add(bQuery2.build(), BooleanClause.Occur.FILTER);
		}
		if (body.getNoSearchKeys() != null)
			// 不扫描列表
			for (String key : body.getNoSearchKeys()) {
				for (int y = 0; y < QUERIES_INDEX_NAMES.length; y++) {
					Query query2 = new PhraseQuery(0, QUERIES_INDEX_NAMES[y], key.split(""));
					bQuery.add(query2, BooleanClause.Occur.MUST_NOT);
				}
			}
		String va = WindwosA.getcomboBox2().getValue();
		// 是否盘符搜索
		if (va != null && !IndexStringConstants.SYPF.equals(va)) {
			TermQuery tq = new TermQuery(new Term(FieldConstant.FILE_PANFU, va));
			bQuery.add(tq, BooleanClause.Occur.MUST);
			tq = null;
		}
		va = WindwosA.getcomboBox().getValue();
		if (va != null)
			switch (va) {
			case IndexStringConstants.QBLX:
				BooleanQuery.Builder bQuery2 = new BooleanQuery.Builder();

				if (WindwosA.getCb2().isSelected()) {

					IndexStringConstants.simpleSuffixList.forEach(s -> {
						TermQuery tq = new TermQuery(new Term(FieldConstant.FILE_SUFFIX, s));
						bQuery2.add(tq, BooleanClause.Occur.SHOULD);
					});
				} else {
					IndexStringConstants.suffixList.forEach(s -> {
						TermQuery tq = new TermQuery(new Term(FieldConstant.FILE_SUFFIX, s));
						bQuery2.add(tq, BooleanClause.Occur.SHOULD);
					});
					TermQuery tq = new TermQuery(new Term(FieldConstant.FILE_SUFFIX, "其他"));
					bQuery2.add(tq, BooleanClause.Occur.SHOULD);
				}
				bQuery.add(bQuery2.build(), BooleanClause.Occur.FILTER);
				break;

			case IndexStringConstants.WBLX:
				BooleanQuery.Builder bQuery3 = new BooleanQuery.Builder();
				if (WindwosA.getCb2().isSelected()) {
					TermQuery tq = new TermQuery(new Term(FieldConstant.FILE_SUFFIX, ".TXT"));
					bQuery3.add(tq, BooleanClause.Occur.SHOULD);
				} else {
					TxtEnums.getValues().forEach(txt -> {
						TermQuery tq = new TermQuery(new Term(FieldConstant.FILE_SUFFIX, txt));
						bQuery3.add(tq, BooleanClause.Occur.SHOULD);
					});
				}
				bQuery.add(bQuery3.build(), BooleanClause.Occur.FILTER);
				break;

			case IndexStringConstants.QT:
				TermQuery tq2 = new TermQuery(new Term(FieldConstant.FILE_SUFFIX, "其他"));
				bQuery.add(tq2, BooleanClause.Occur.FILTER);
				break;

			default:
				TermQuery tq = new TermQuery(new Term(FieldConstant.FILE_SUFFIX, va));
				bQuery.add(tq, BooleanClause.Occur.FILTER);
				break;
			}
		return bQuery.build();
	}

	/**
	 * 分页查询
	 * 
	 * @param page
	 */
	public static MyFile search(SearchBody body, Query query, int totalNum, ScoreDoc after) {

		MyFile page = new MyFile();
		TopDocs docs = null;
		IndexSearcher searcher = MyDirectoryS.getIndexSearcher();

		try {
			if (body.getPageNum() == 1 && after == null) {
				int maxLegth = 0;
				if (body.isHasFirst())
					maxLegth = page.getPageSize();
				else
					maxLegth = Integer.MAX_VALUE;
				docs = searcher.search(new MyScoreUtil(query, body.getSearchKeys()), maxLegth);
			} else {
				docs = searcher.searchAfter(after, new MyScoreUtil(query, body.getSearchKeys()), page.getPageSize());
			}
			if (totalNum == -1)
				page.setTotalResultNum(docs.scoreDocs.length);
			else
				page.setTotalResultNum(totalNum);
		} catch (IOException e) {
			e.printStackTrace();
		}

		int tempSize = (docs.scoreDocs.length > page.getPageSize() ? page.getPageSize() : docs.scoreDocs.length);
		for (int i = 0; i < tempSize; i++) {
			ScoreDoc sdoc = docs.scoreDocs[i];
			if (i == tempSize - 1) {
				page.setAfterScoreDoc(sdoc);
			}
			try {
				Document doc = searcher.doc(sdoc.doc);
				page.getDocList().add(doc);
				doc = null;
			} catch (Exception e) {
				// MyDirectoryS.updateReaderAndSearcher();
			}
		}
		return page;
	}

	public static void delOld() {

		SearchBody body = new SearchBody();
		body.setSearchKeys(new String[] { "." });
		Query query = buildQuery(body);
		try {
			IndexSearcher searcher = MyDirectoryS.getIndexSearcher();
			ScoreDoc doc;
			Document docc;
			TopDocs docs = searcher.search(query, Integer.MAX_VALUE);
			Path path;
			for (int i = 0; i < docs.scoreDocs.length; i++) {
				doc = docs.scoreDocs[i];
				docc = searcher.doc(doc.doc);
				path = Paths.get(docc.get(FieldConstant.FILE_PATH));
				if (!Files.exists(path)) {
					MyDirectoryS.writer
							.deleteDocuments(new Term(FieldConstant.FILE_PATH, docc.get(FieldConstant.FILE_PATH)));
				}
				docc.clear();
				docc = null;
			}
			docs = null;
		} catch (IOException e) {

			e.printStackTrace();
		}
	}
}
